CONTINUACIONES
(CONTINUATION-
PASSING STYLE
, CPS)

Parametrización funcional de funciones

Continuation-passing style es una notación de programa que hace explícito cada aspecto del flujo de control y de datos” (Andrew W. Appel)



La Técnica CPS

Definición

CPS es una técnica de programación funcional que consiste en lo siguiente: La función c con argumento r representa lo que “falta por hacer” (tras la obtención del primer resultado r) para completar el resultado final de la función f. Es por ello que a c se le denomina “función continuación” o, simplemente, “continuación”. Y a la función que incluye como parámetro una función continuación se le denomina “función con continuación” o “función CPS”.


Diferencia entre las funciones f(a, c) y c(f(a))

En ambos casos el resultado es el mismo, pero hay importantes diferencias:
  1. En la primera función, c es un parámetro y en la segunda no.

  2. En la primera función, tras la ejecución y obtención del resultado r, se invoca a c (con argumento r). Posteriormente se devuelve el control. En la segunda función, tras la obtención de r, hay retorno (del resultado y del control) a la función c.

  3. En el primer caso, puede haber continuaciones de orden superior, es decir, la continuación podría invocar a su vez a otra función con continuación, que a su vez podría llamar a otra función con continuación, etc., por lo que la función está funcionalmente abierta. En el segundo caso, la función está funcionalmente cerrada.

Implementación en MENTAL

Especificación

La función CPS en MENTAL se puede representar de la forma clásica (con los parámetros entre paréntesis) f(x c) siendo: Definición:
Ejemplo
  1. Estilo normal.

    Definición de función:
    ⟨( cuadrado(x) = x*x )⟩

    Uso de la función:
    cuadrado(4) // ev. 4*4 ev. 16

  2. CPS.

    Definición de función (se añade un parámetro adicional):
    ⟨( cuadrado(x c) = c(x*x) )⟩

    Definición de una función continuación:
    ⟨( sumar5(x) = x+5 )⟩

    Uso de la función:
    cuadrado(4 sumar5) // ev. sumar5(4*4) ev. sumar5(16) ev. 16+5 ev. 21

    Definición de otra función continuación:
    ⟨( prod5(x) = 5*x )⟩

    Uso de la función con la nueva función continuación:
    cuadrado(4 prod5) // ev. prod5(4*4) ev. prod5(16) ev. 5*16 ev. 80

Función continuación con parámetros

La función c representa a una función de cualquier número de parámetros. Por ejemplo, generalizando el ejemplo anterior mediante un parámetro, Un ejemplo de función continuación con dos parámetros es el siguiente: Obsérvese que es necesario separar los parámetros propios de la función continuación del parámetro correspondiente al resultado de la función CPS.


Continuación nula

En la función CPS si utilizamos como continuación la expresión nula (θ), tenemos, por ejemplo: Por lo tanto, cuando la continuación es nula, estamos en el estilo normal.


Variables ligadas y libres en CPS

Una función CPS −como toda expresión genérica parametrizada− tiene variables de dos tipos: Ejemplo:
Continuación en funciones recursivas

La aplicación de una continuación a una función recursiva produce una nueva función (extendida) que se aplica a la función recursiva original.

Ejemplo con factorial:
  1. Estilo normal:

    ⟨( fac(n) = (1 ← n=1 →' n*fac(n−1)) )⟩

    fac(4) // ev. 4*3*2*1 ev. 24


  2. CPS:

    ⟨( facx(n c) = (c(fac(n)) )⟩

    Si utilizamos la función continuación

    ⟨( lineal(a b)(x) = (a*x + b) )⟩

    tenemos:

    facx(4 lineal(2 5)) // ev. lineal(2 5)(24) ev. 224+5 ev. 53
Ejemplo con la secuencia de Fibonacci: 1, 1, 2, 3, 5, 8, 13, …
  1. Estilo normal:

    ⟨( fibo(n) = (1 ← n>2 →' (fibo(n−1) + fibo(n−2))) )⟩

    fibo(1) // ev. 1
    fibo(2) // ev. 1
    fibo(3) // ev. 2
    fibo(4) // ev. 3
    fibo(5) // ev. 5
    ...


  2. CPS:

    ⟨( fibox(n c) = c(fibo(n)) )⟩

    Si utilizamos la función continuación

    ⟨( doble(x) = 2*x )⟩

    tenemos:

    fibox(1 doble) // ev. doble(1) ev. 2
    fibox(2 doble) // ev. doble(1) ev. 2
    fibox(3 doble) // ev. doble(2) ev. 4
    fibox(4 doble) // ev. doble(3) ev. 6
    fibox(5 doble) // ev. doble(5) ev. 10
    ...


    Lo que se obtiene son los valores dobles de la secuencia de Fibonacci.

Continuaciones de orden superior

Una función continuación puede, a su vez, tener otra función continuación. La forma general para dos funciones continuación es

⟨( f(x c1 c2) = c2(c1(f(x))) )⟩

Por ejemplo: Definición de una función continuación c1: Definición de una función continuación c2: Uso de la función: Las funciones continuación de orden superior podrían tener, a su vez, parámetros.


Más allá de CPS. La parametrización de expresiones

La técnica CPS es la parametrización funcional de funciones, pero es un caso particular del caso general de adición de parámetros a expresiones, que puede hacerse en MENTAL. Ejemplos de función sobre resultados intermedios (no sobre el resultado final):
  1. Factorial:

    ⟨( fac(n c) = (c(1) ← n=1 →' c(n)*fac(n−1 c))) )⟩


    Si c=θ, tenemos la función factorial normal.

    Si utilizamos la función ⟨( doble(x) = x*2 )⟩, tenemos:


  2. Secuencia de Fibonacci: 1, 1, 2, 3, 5, 8, 13, ...

    ⟨( fibo(n c) = (c(1) ← n>2 →' c(fibo(n−1 c) + fibo(n−2 c)))) )⟩


    Si c=θ, tenemos la función de Fibonacci normal.

    Si utilizamos la misma función anterior (doble) como c, tenemos:

Ejemplos de parametrización de datos:
  1. ⟨(unodos(c) = c(12))⟩

    Parametrización mediante una función:


    Parametrización mediante datos:


  2. ⟨( registro(c) = (c(6) c(12) c(9) c(17) c(8)) )⟩

    Parametrización mediante una función:


    Parametrización mediante datos:


  3. ⟨( registro(c) = (6 12 9 17 8)c )⟩

    Parametrización mediante una función:


    Parametrización mediante datos:


Conclusiones

En los lenguajes de programación tradicionales, f es fijo (no puede ser variable). En MENTAL, sí puede ser variable, por lo que el concepto de continuación es irrelevante, pues da lo mismo incluir la continuación como parámetro o como función. Por ejemplo, Nombre de la función variable: Nombre de la función continuación variable: Nombre de la función variable y nombre de la función continuación variable:

Adenda

Características principales de la técnica CPS
Aplicaciones de la técnica CPS

La técnica CPS nació a finales de los años 1960s. Desde entonces, además de su aplicación mencionada en el desarrollo de compiladores e intérpretes, también se ha aplicado en diversidad de áreas:
Bibliografía